package com.md.common.utils.beetl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 功能描述：对beetl的日期格式化扩展：支持java8的LocalTime,LocalDate,LocalDateTime
 *
 * @author lujianping@oak168.com
 * @version 1.0
 * @date 2018-6-14 11:51
 * @since JDK 1.8
 */
public class DateFormat extends org.beetl.ext.format.DateFormat {

    private static final String DEFAULT_KEY = "default";

    private static Map<String, DateTimeFormatter> formatMap = new ConcurrentHashMap<>();

    static {
        formatMap.put(DEFAULT_KEY, DateTimeFormatter.ofPattern("", Locale.getDefault(Locale.Category.FORMAT)));
    }

    @Override
    public Object format(Object data, String pattern) {
        if (data == null)
            return null;
        Class<?> target = data.getClass();
        if (LocalTime.class.isAssignableFrom(target)) {
            return ((LocalTime) data).format(getFormatter(pattern));
        } else if (LocalDate.class.isAssignableFrom(target)) {
            return ((LocalDate) data).format(getFormatter(pattern));
        } else if (LocalDateTime.class.isAssignableFrom(target)) {
            return ((LocalDateTime) data).format(getFormatter(pattern));
        } else { // Calendar,Date,Long
            if (Calendar.class.isAssignableFrom(target)) {
                data = ((Calendar) data).getTime();
            }
            return super.format(data, pattern);
        }
    }

    /**
     * 获取格式化表达式
     *
     * @return 格式化表达式
     */
    protected DateTimeFormatter getFormatter(String pattern) {
        if (pattern == null) {
            pattern = DEFAULT_KEY;
        }
        DateTimeFormatter formatter = formatMap.get(pattern);
        if (formatter == null) {
            formatter = DateTimeFormatter.ofPattern(pattern, Locale.getDefault(Locale.Category.FORMAT));
            formatMap.put(pattern, formatter);
        }
        return formatter;
    }
}

